package com.zz.study.sharding.entity;

import com.zz.study.sharding.util.GPSUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 区域的经纬度点，格式标准 ，区域由多边形的多个顶点来定义
 *
 * [[longitude1,latitude1],[longitude2,latitude2]]  <=====> List<GPSLocation>
 */

/**
 * 经纬度点 对象
 */
@Data
@ApiModel(value = "经纬度点模型")
public class GPSLocation {

    /**
     * 地点中文显示
     */
    private String locationInChinese;

    /**
     * 经度显示成度分秒，可以不传
     */
    private String longitudeDFM;
    /**
     * 纬度显示成度分秒，可以不传
     */
    private String latitudeDFM;

    @ApiModelProperty(value = "纬度,数字类型",required = true)
    private double latitude;

    @ApiModelProperty(value = "经度,数字类型",required = true)
    private double longitude;

    public static final String openParenthese = "[";

    public static final String closeParenthese = "]";

    public static final String splitor = ",";

    public GPSLocation( ) {

    }

    public GPSLocation(String encodeStr) {
            this.longitude =   decodeObj(encodeStr).getLongitude();
            this.latitude = decodeObj(encodeStr).getLatitude();
        this.longitudeDFM = GPSUtil.changeToDFM(this.longitude);
        this.latitudeDFM = GPSUtil.changeToDFM(this.latitude);
    }

    public GPSLocation convertDFM(){
        this.longitudeDFM = GPSUtil.changeToDFM(this.longitude);
        this.latitudeDFM = GPSUtil.changeToDFM(this.latitude);
        return this;
    }

    /**
     * 转化成度分秒
     * @return
     */
    public String convertDFMStr(){
        this.longitudeDFM = GPSUtil.changeToDFM(this.longitude);
        this.latitudeDFM = GPSUtil.changeToDFM(this.latitude);
        StringBuilder str = new StringBuilder();

        str.append(longitudeDFM);
        if(this.longitude>=0){
            str.append("E");
        }else{
            str.append("W");
        }
        str.append(splitor);
        str.append(latitudeDFM);
        if(this.longitude>=0){
            str.append("N");
        }else{
            str.append("S");
        }
        return str.toString();
    }
    /**
     * 转化成度分秒
     * @return
     */
    public GPSLocation convertDFM(GPSLocation location){
        location.setLongitudeDFM(GPSUtil.changeToDFM(location.getLongitude()));
        location.setLatitudeDFM(GPSUtil.changeToDFM(location.getLongitude()));
        return this;
    }


    public GPSLocation(double longitude, double latitude) {
        if(longitude>latitude){
            this.latitude = latitude;
            this.longitude = longitude;
        }else{
            this.latitude = longitude;
            this.longitude = latitude;
        }

    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    /**
     * 编码成字符串
     * @return
     */
    public  String encode(){
        return openParenthese+
                Double.valueOf(longitude).toString()+
                splitor+
                Double.valueOf(latitude).toString()+
                closeParenthese;
    }
    /**
     * 序列化成字符串
     * @return
     */
    public static  String encode(double longitudeV,double latitudeV){
        //经度的值比纬度大
        if(longitudeV>latitudeV){
            return openParenthese+
                    Double.valueOf(longitudeV).toString()+
                    splitor+
                    Double.valueOf(latitudeV).toString()+
                    closeParenthese;
        }else {
            return openParenthese+
                    Double.valueOf(latitudeV).toString()+
                    splitor+
                    Double.valueOf(longitudeV).toString()+
                    closeParenthese;
        }

    }

    public static  String encodeObj(GPSLocation gpsLocation){
        return openParenthese+
                Double.valueOf(gpsLocation.getLongitude()).toString()+
                splitor+
                Double.valueOf(gpsLocation.getLatitude()).toString()+
                closeParenthese;
    }


    public static  String encodeList(List<GPSLocation> gpsLocationList){
        StringBuilder sb = new StringBuilder();
        sb.append(openParenthese);
        for(GPSLocation location:gpsLocationList){
            sb.append(location.encodeObj(location));
            sb.append(splitor);
        }
        String originalStr = sb.toString();
        String temp = originalStr.substring(0,originalStr.lastIndexOf(splitor));
        return temp +closeParenthese;
    }

    /**
     * 反序列化成对象
     * @param gpsStr
     * @return
     */
    public static GPSLocation decodeObj(String gpsStr){
        int openParentheseIndex = gpsStr.indexOf(openParenthese);
        int splitorIndex = gpsStr.indexOf(splitor);
        int closeParentheseIndex = gpsStr.indexOf(closeParenthese);
        Double longitudeVal = Double.valueOf(gpsStr.substring(openParentheseIndex+1,splitorIndex));
        Double latitudeVal = Double.valueOf(gpsStr.substring(splitorIndex+1,closeParentheseIndex));
        if((!Objects.isNull(longitudeVal)) && (!Objects.isNull(latitudeVal)) && (longitudeVal>latitudeVal)){
            return new GPSLocation(longitudeVal,latitudeVal);
        }else if((!Objects.isNull(longitudeVal)) && (!Objects.isNull(latitudeVal)) && (longitudeVal<latitudeVal)){
            return new GPSLocation(latitudeVal,longitudeVal);
        }
        return new GPSLocation(longitudeVal,latitudeVal);
    }
    /**
     * 反序列化成经纬度点数组对象
     * @param gpsList
     * @return
     */
    public static List<GPSLocation> decodeList(String gpsList, boolean stringIslongitudeFront){

        int firstOpenParenthese = gpsList.indexOf(openParenthese);
        int lastCloseParenthese = gpsList.lastIndexOf(closeParenthese);
        String tempStr = gpsList.substring(firstOpenParenthese+1,lastCloseParenthese);
        char[] tokenArray= tempStr.toCharArray();
        List<Integer> gpsObjectOpenParentheseArray = new ArrayList<>();
        List<Integer> gpsObjectCloseParentheseArray = new ArrayList<>();
        for(int i=0;i<tokenArray.length;i++){
            if("[".equals(String.valueOf(tokenArray[i]))){
                gpsObjectOpenParentheseArray.add(i);
            }else if("]".equals(String.valueOf(tokenArray[i]))){
                gpsObjectCloseParentheseArray.add(i);
            }else {
                continue;
            }
        }
        List<GPSLocation> gpsLocationList = new ArrayList<>();
        for(int j=0;j<gpsObjectOpenParentheseArray.size();j++){
            if(stringIslongitudeFront){
                String locationTupleStr = tempStr.substring(gpsObjectOpenParentheseArray.get(j)+1,
                        gpsObjectCloseParentheseArray.get(j));
                String longitude=   locationTupleStr.split(splitor)[0];
                String latitude = locationTupleStr.split(splitor)[1];
                GPSLocation location = new GPSLocation(Double.valueOf(longitude.trim()),Double.valueOf(latitude.trim()));
                gpsLocationList.add(location);
            }else{
                String locationTupleStr = tempStr.substring(gpsObjectOpenParentheseArray.get(j)+1,
                        gpsObjectCloseParentheseArray.get(j));
                String latitude=   locationTupleStr.split(splitor)[0];
                String longitude = locationTupleStr.split(splitor)[1];
                GPSLocation location = new GPSLocation(Double.valueOf(longitude.trim()),Double.valueOf(latitude.trim()));
                gpsLocationList.add(location);
            }
        }
        return gpsLocationList;

    }
}
